home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Selection / Multimedia Selection Volume One - CD-ROM / MULTIMEDIA SELECTION____________.ISO / grafica / dos / theimage / thedraw.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-07-30  |  9.3 KB  |  202 lines

  1.  
  2. UNIT THEDRAW;
  3.  
  4.  
  5.   (* This is (almost) the original UNCRUNCH.PAS file bundled with TheDraw
  6.      version 4.60 package. I have made some minor text cosmetics (indentations
  7.      and stuff like that), and way from that and the fact that I have
  8.      transformed it in a plain Turbo Pascal source code Unit, everything else
  9.      remains exactly the same, as is distributed with TheDraw.
  10.  
  11.      This source code, distributed along with TheImage, is only included for
  12.      demo purposes and quick operation results, since this source code is
  13.      Copyrighted (C) 1986-1993 by TheSoft Programming Services and Ian E.
  14.      Davis. All Rights are Reserved. P.O. Box 7657. Fremont, CA. 94537-7657.
  15.      USA. Please refer to TheDraw documentation for further details.
  16.  
  17.      <José De Almeida> *)
  18.  
  19.  
  20. INTERFACE
  21.  
  22.  
  23.  
  24. PROCEDURE UnCrunch(var Addr1, Addr2; BlkLen : Integer);
  25.  
  26.  
  27.  
  28. IMPLEMENTATION
  29.  
  30.  
  31.  
  32. PROCEDURE UnCrunch(var Addr1, Addr2; BlkLen : Integer);
  33.  
  34. (* ---------------------------------------------------------------------------
  35.    This is the routine for displaying crunched TheDraw image files. The
  36.    crunched data format is a simple custom protocol for reproducing any image.
  37.    The control codes below decimal 32 are reserved for this function.
  38.    Characters 32 and above are written directly to the destination address.
  39.  
  40.    The following shows the format of a control code sequence. Please note that
  41.    not all functions use the optional bytes <x> or <y>.
  42.  
  43.    Data Structure:  <current byte>[<x>[<y>]]
  44.  
  45.       0..15 = New Foreground Color
  46.      16..23 = New Background Color
  47.          24 = Go down to next line, return to same horizontal position as when
  48.               routine was started (akin to a c/r).
  49.          25 = Displays <x> number of spaces.
  50.          26 = Displays <x> number of <y>.  Also used to display ANY characters
  51.               below #32.  This function is the only way to do this although it
  52.               uses three bytes.  Otherwise the code would be interpreted as
  53.               another command.
  54.          27 = Toggles on/off the foreground attribute blink flag.
  55.      28..31 = reserved
  56.  
  57.    ---------------------------------------------------------------------------
  58.  
  59.    To use this routine, call the procedure with the crunched image data as the
  60.    first parameter, the display address as the second parameter, and the
  61.    length of the crunched image data as the third parameter.
  62.  
  63.    Assume we have an ImageData file of a 40 character by 10 line block. Also
  64.    the following defintions. ie:
  65.  
  66.      { TheDraw Pascal Crunched Screen Image }
  67.      const                          { This CONST area is ImageData_Width = 40;
  68.                                       generated by TheDraw }
  69.        ImageData_Depth  = 10;
  70.        ImageData_Length = 467;
  71.        ImageData        : array [1..467] of char =
  72.        (...list of image bytes here...);
  73.  
  74.      type
  75.        ScreenType = array [0..3999] of byte;
  76.  
  77.      var
  78.        ScreenAddr : ScreenType absolute $B800:$0000;
  79.  
  80.      BEGIN
  81.        UnCrunch(ImageData,ScreenAddr[(34*2) + (5*160) -162],ImageData_Length);
  82.      END;
  83.  
  84.  
  85.    SCREENADDR is a variable mapped to the same location as the physical video
  86.    addresses (via Turbo's absolute addressing). The rather messy array offset
  87.    tells UnCrunch where to start displaying the ImageData block. The 34*2
  88.    indicates the horizontal position number 34 with the 5*160 indicating line
  89.    number 5. This is similar to a Turbo GOTOXY (34,5) statement.
  90.  
  91.    The original horizontal starting offset is remembered by the uncrunch
  92.    routine. The offset is restored upon moving down to the next line. This
  93.    permits a block to be displayed correctly anywhere on the screen. ie:
  94.  
  95.                  ┌─ horizontal starting offset
  96.                  V
  97.      +-------------------------------------------------+
  98.      |                                                 |
  99.      |                                                 | <- Assume this
  100.      |                                                 |    is the video
  101.      |           ┌─────────────────────┐               |    display.
  102.      |           │█████████████████████│               |
  103.      |           │█████████████████████│               |
  104.      |           │██ ImageData block ██│               |
  105.      |           │█████████████████████│               |
  106.      |           │█████████████████████│               |
  107.      |           │█████████████████████│               |
  108.      |           └─────────────────────┘               |
  109.      |                                                 |
  110.      |                                                 |
  111.      |                                                 |
  112.      +-------------------------------------------------+
  113.  
  114.  
  115.    The ImageData block could just as well have been display in the upper-left
  116.    corner of the screen with:
  117.  
  118.      UnCrunch(ImageData,ScreenAddr[(1*2) + (1*160) -162],ImageData_Length);
  119.  
  120.    Notice the array address changed to the equivilant of GotoXY(1,1);
  121.  
  122.    To display the block in the lower-right corner you would use:
  123.  
  124.      UnCrunch(ImageData,ScreenAddr[(40*2) + (15*160) -162],ImageData_Length);
  125.  
  126.    In this example, the block is 40 characters wide by 10 lines deep. Thus, to
  127.    display such a large block, we must display the block at GOTOXY (40,15);
  128.  
  129.    That's it! The routine was designed for easy use and understanding;
  130.    however, for some people the best way is to experiment. Create a program
  131.    using the above examples, perhaps with a 40x10 block (or any size).
  132.    Good luck! *)
  133.  
  134. BEGIN { UnCrunch }
  135.   inline (
  136.     $1E/               {       PUSH    DS             ;Save data segment.}
  137.     $C5/$B6/ADDR1/     {       LDS     SI,[BP+Addr1]  ;Source Address}
  138.     $C4/$BE/ADDR2/     {       LES     DI,[BP+Addr2]  ;Destination Addr}
  139.     $8B/$8E/BLKLEN/    {       MOV     CX,[BP+BlkLen] ;Length of block}
  140.     $E3/$5B/           {       JCXZ    Done}
  141.     $8B/$D7/           {       MOV     DX,DI          ;Save X coordinate for later.}
  142.     $33/$C0/           {       XOR     AX,AX          ;Set Current attributes.}
  143.     $FC/               {       CLD}
  144.     $AC/               {LOOPA: LODSB                  ;Get next character.}
  145.     $3C/$20/           {       CMP     AL,32          ;If a control character, jump.}
  146.     $72/$05/           {       JC      ForeGround}
  147.     $AB/               {       STOSW                  ;Save letter on screen.}
  148.     $E2/$F8/           {Next:  LOOP    LOOPA}
  149.     $EB/$4C/           {       JMP     Short Done}
  150.                        {ForeGround:}
  151.     $3C/$10/           {       CMP     AL,16          ;If less than 16, then change the}
  152.     $73/$07/           {       JNC     BackGround     ;foreground color.  Otherwise jump.}
  153.     $80/$E4/$F0/       {       AND     AH,0F0H        ;Strip off old foreground.}
  154.     $0A/$E0/           {       OR      AH,AL}
  155.     $EB/$F1/           {       JMP     Next}
  156.                        {BackGround:}
  157.     $3C/$18/           {       CMP     AL,24          ;If less than 24, then change the}
  158.     $74/$13/           {       JZ      NextLine       ;background color.  If exactly 24,}
  159.     $73/$19/           {       JNC     FlashBitToggle ;then jump down to next line.}
  160.     $2C/$10/           {       SUB     AL,16          ;Otherwise jump to multiple output}
  161.     $02/$C0/           {       ADD     AL,AL          ;routines.}
  162.     $02/$C0/           {       ADD     AL,AL}
  163.     $02/$C0/           {       ADD     AL,AL}
  164.     $02/$C0/           {       ADD     AL,AL}
  165.     $80/$E4/$8F/       {       AND     AH,8FH         ;Strip off old background.}
  166.     $0A/$E0/           {       OR      AH,AL}
  167.     $EB/$DA/           {       JMP     Next}
  168.                        {NextLine:}
  169.     $81/$C2/$A0/$00/   {       ADD     DX,160         ;If equal to 24,}
  170.     $8B/$FA/           {       MOV     DI,DX          ;then jump down to}
  171.     $EB/$D2/           {       JMP     Next           ;the next line.}
  172.                        {FlashBitToggle:}
  173.     $3C/$1B/           {       CMP     AL,27          ;Does user want to toggle the blink}
  174.     $72/$07/           {       JC      MultiOutput    ;attribute?}
  175.     $75/$CC/           {       JNZ     Next}
  176.     $80/$F4/$80/       {       XOR     AH,128         ;Done.}
  177.     $EB/$C7/           {       JMP     Next}
  178.                        {MultiOutput:}
  179.     $3C/$19/           {       CMP     AL,25          ;Set Z flag if multi-space output.}
  180.     $8B/$D9/           {       MOV     BX,CX          ;Save main counter.}
  181.     $AC/               {       LODSB                  ;Get count of number of times}
  182.     $8A/$C8/           {       MOV     CL,AL          ;to display character.}
  183.     $B0/$20/           {       MOV     AL,32}
  184.     $74/$02/           {       JZ      StartOutput    ;Jump here if displaying spaces.}
  185.     $AC/               {       LODSB                  ;Otherwise get character to use.}
  186.     $4B/               {       DEC     BX             ;Adjust main counter.}
  187.                        {StartOutput:}
  188.     $32/$ED/           {       XOR     CH,CH}
  189.     $41/               {       INC     CX}
  190.     $F3/$AB/           {       REP STOSW}
  191.     $8B/$CB/           {       MOV     CX,BX}
  192.     $49/               {       DEC     CX             ;Adjust main counter.}
  193.     $E0/$AA/           {       LOOPNZ  LOOPA          ;Loop if anything else to do...}
  194.     $1F);              {Done:  POP     DS             ;Restore data segment.}
  195. END; { UnCrunch }
  196.  
  197.  
  198.  
  199. END. { THEDRAW.PAS }
  200.  
  201.  
  202.